package com.tbit.main.controller;

import com.tbit.common.constant.MethodEnum;
import com.tbit.common.constant.ModuleEnum;
import com.tbit.common.utils.TraceUtil;
import com.tbit.main.common.JsonResult;
import com.tbit.main.constant.*;
import com.tbit.main.constant.OperateLog;
import com.tbit.main.constant.enums.ParkPointType;
import com.tbit.main.exception.BaseException;
import com.tbit.main.pojo.*;
import com.tbit.main.pojo.VO.DetentionMachineBoundVO;
import com.tbit.main.pojo.VO.DetentionVo;
import com.tbit.main.service.*;
import com.tbit.main.util.Assert;
import com.tbit.main.util.GeoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 扣押区
 *
 * @Author: chen
 * @Description:
 * @Date: 创建于 18:45 2023/2/7
 */
@RestController
@RequestMapping("/detentionArea")
public class DetentionAreaController {

    @Autowired
    private DetentionAreaService detentionAreaService;
    @Autowired
    private DetentionMachineBoundService detentionMachineBoundService;
    @Autowired
    private CalibrateService calibrateService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private RoleMenuService roleMenuService;

    /**
     * 获取区域所有扣押区
     *
     * @param accountId 区域id
     * @return
     */
    @RequestMapping("/getByAccountId")
    public JsonResult getByAccountId(Integer accountId, @RequestParam(defaultValue = "2") Integer mapType) {
        Assert.notNull(accountId, "AccountUser.agentId.notNull");
        return detentionAreaService.getByAccountId(accountId, mapType);
    }

    /**
     * 新增
     *
     * @param detentionArea
     * @param mapType
     * @return
     */
    @RequestMapping("/add")
    @OperateLog(module = ModuleEnum.MAINDETENTIONAREA, methods = MethodEnum.DETENTIONAREA_ADD)
    public JsonResult add(DetentionArea detentionArea, @RequestParam(defaultValue = "2") Integer mapType,String token) {
        DetentionArea detentionAreaByName = detentionAreaService.getByDetentionAreaName(detentionArea.getAccountId(), detentionArea.getName());
        if (detentionAreaByName != null) {
            throw new BaseException("该运营区内有重复的扣押区名称");
        }
        AccountUser accountUser = tokenService.getAccount(token);
        Role role = accountUser.getRole();
        List<Menu> roleType = roleMenuService.getRoleType(role.getRoleId());
        //菜单名称
        List<String> collect = roleType.stream().map(menu -> menu.getMenuName()).collect(Collectors.toList());
        if (!collect.contains("扣押区管理")){
            return JsonResult.fail(500, "当前人员没有权限", TraceUtil.getTraceIdByLocal());
        }
        check(detentionArea);
        return  detentionAreaService.add(detentionArea, mapType);
    }

    /**
     * 更新
     *
     * @param detentionArea
     * @param mapType
     * @return
     */
    @RequestMapping("/edit")
    @OperateLog(module = ModuleEnum.MAINDETENTIONAREA, methods = MethodEnum.DETENTIONAREA_UPDATE)
    public JsonResult edit(DetentionArea detentionArea, @RequestParam(defaultValue = "2") Integer mapType) {
        Assert.notNull(detentionArea.getDetentionId(), "detentionArea.id.notNull");
        DetentionArea detentionAreaByName = detentionAreaService.getByDetentionAreaName(detentionArea.getAccountId(), detentionArea.getName());
        if (detentionAreaByName != null && !Objects.equals(detentionArea.getDetentionId(), detentionAreaByName.getDetentionId())) {
            throw new BaseException("该运营区内有重复的扣押区名称");
        }
        check(detentionArea);
        return detentionAreaService.edit(detentionArea, mapType);

    }

    /**
     * 删除
     *
     * @param detentionId
     * @return
     */
    @RequestMapping("/del")
    @OperateLog(module = ModuleEnum.MAINDETENTIONAREA, methods = MethodEnum.DETENTIONAREA_DEL)
    public JsonResult del(Integer detentionId) {
        List<DetentionMachineBoundVO> byDetentionId = detentionMachineBoundService.getByDetentionId(detentionId);
        if (byDetentionId != null && byDetentionId.size()>0){
            return JsonResult.fail(500, "当前扣押区还有车辆",TraceUtil.getTraceIdByLocal());
        }
        boolean result = detentionAreaService.removeById(detentionId);
        return result ? JsonResult.succ() : JsonResult.fail(null, "",TraceUtil.getTraceIdByLocal());
    }

    /***
     * 前置非空校验
     * @param detentionArea
     */
    void check(DetentionArea detentionArea) {
        Assert.notNull(detentionArea.getType(), "ParkPoint.type.notNull");
        Assert.hasLength(detentionArea.getName(), "ParkPoint.name.notNull");
        Assert.notNull(detentionArea.getAllowRange(), "ParkPoint.allowRange.notNull");
        Assert.notNull(detentionArea.getAccountId(), "AccountUser.agentId.notNull");
        if (ParkPointType.PARKPOINT_CIRCULAR_TYPE.getType().equals(detentionArea.getType())) {
            Assert.notNull(detentionArea.getLo(), "Map.lon.nutNull");
            Assert.notNull(detentionArea.getLa(), "Map.lat.nutNull");
            detentionArea.setLoC(detentionArea.getLo());
            detentionArea.setLaC(detentionArea.getLa());
        } else if (ParkPointType.PARKPOINT_POLYGON_TYPE.getType().equals(detentionArea.getType())) {
            Assert.notNull(detentionArea.getPoints(), "ParkPoint.points.notNull");

            /** 计算电子围栏中心点 */
            List<Point> points = GeoUtil.getPoints(detentionArea.getPoints());
            Point newPoint = GeoUtil.GetCenterPoint(points);
            detentionArea.setLa(newPoint.getY());
            detentionArea.setLo(newPoint.getX());
            /** 保存高德地图原始经纬度 */
            detentionArea.setLaC(newPoint.getY());
            detentionArea.setLoC(newPoint.getX());
            detentionArea.setPointsC(detentionArea.getPoints());


        }
    }

    /**
     * 获取扣押区下扣押车辆
     *
     * @param accountId 区域id
     * @return
     */
    @RequestMapping("/getAllDetention")
    public JsonResult getAllDetention( Integer accountId) {

        Assert.notNull(accountId, "AccountUser.agentId.notNull");
        List<DetentionVo> allWarehouse = detentionAreaService.getAllDetention(accountId);
        return JsonResult.succ(allWarehouse);

    }


    /**
     * 根据定位查询
     *
     * @param
     * @return
     */
    @RequestMapping("/getNearDetention")
    public JsonResult getNearDetention(DetentionArea detentionArea, Integer mapType) {

        Assert.notNull(detentionArea.getAccountId(), "AccountUser.agentId.notNull");

        if (mapType == null) {
            mapType = SysConstant.GOOGLE;
        }

        if (detentionArea != null) {
            /** 校准 */
            calibrateService.calDetentionArea(detentionArea, mapType, SysConstant.ORIGINAL);
        }

        DetentionArea DetentionBack = detentionAreaService.getNearDetention(detentionArea.getAccountId(), detentionArea.getLo(), detentionArea.getLa(),null);
        if (DetentionBack != null) {
            /** 校准 */
            calibrateService.calibrateDetentionArea(DetentionBack, mapType);
            return JsonResult.succ(DetentionBack);
        }
        return JsonResult.fail(500, "当前定位没有扣押区",TraceUtil.getTraceIdByLocal());

    }


    /**
     * 查询附近附件扣押区
     */
    @RequestMapping("/getNear")
    public JsonResult getNear(@RequestParam("userCodeS")String userCodeS, Integer mapType,Integer accountId) {
        return    detentionAreaService.getNear(userCodeS,mapType,accountId);
    }


    /**
     * 判断是否在推荐扣押区
     */
    @RequestMapping("/checkNear")
    public JsonResult checkNear(@RequestParam("userCodeS")String userCodeS, Integer mapType,Integer accountId,Integer detentionId) {
        return    detentionAreaService.checkNear(userCodeS,mapType,accountId,detentionId);
    }


    /**
     * 根据扣押区id获取扣押区
     *
     * @param accountId 区域id
     * @return
     */
    @RequestMapping("/getByDetentionId")
    public JsonResult getByDetentionId(Integer detentionId, @RequestParam(defaultValue = "2") Integer mapType) {
        return detentionAreaService.getByDetentionId(detentionId, mapType);
    }

}
